package com.cc.dy.http;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.URLUtil;
import com.cc.dy.api.response.DyResponse;
import com.cc.dy.executer.DyService;
import com.cc.dy.json.JsonSerializer;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public abstract class AbstractDyHttpClient implements DyHttpClient {

    private final JsonSerializer jsonSerializer;

    protected final DyService dyService;

    public AbstractDyHttpClient(DyService dyService, JsonSerializer jsonSerializer) {
        this.dyService = dyService;
        this.jsonSerializer = jsonSerializer;
    }

    @Override
    public JsonSerializer getJsonSerializer() {
        return jsonSerializer;
    }

    /**
     * GET请求
     *
     * @param url 请求地址
     * @param t   返回对象的类型
     * @return {@link T}
     */
    @Override
    public <T extends DyResponse> T get(String url, Class<T> t) {
        return getWithHeaders(url, null, t);
    }


    /**
     * 当本Service没有实现某个API的时候，可以用这个，针对所有API中的POST请求.
     *
     * @param url     请求接口地址
     * @param request 请求对象
     * @param t       返回对象的类型
     * @return {@link T}
     */
    @Override
    public <T extends DyResponse> T post(String url, Object request, Class<T> t) {
        return postWithHeaders(url, null, request, t);
    }

    /**
     * POST请求
     *
     * @param url     请求接口地址
     * @param headers 请求头
     * @param request 请求对象
     * @param t       类型
     * @return {@link T}
     */
    @Override
    public <T extends DyResponse> T postWithHeaders(String url, Map<String, String> headers, Object request, Class<T> t) {
        return postWithHeaders(url, headers, null, request, t);
    }

    /**
     * 请求路径拼接参数
     *
     * @param url    请求路径拼
     * @param params 参数
     * @return 带参路径
     */
    protected String urlJoinParams(String url, Map<String, Object> params) {
        if (CollectionUtil.isEmpty(params)) {
            return url;
        }
        String buildQuery = URLUtil.buildQuery(params, StandardCharsets.UTF_8);
        if (url.contains("?")) {
            return url + (url.endsWith("&") ? "" : "&") + buildQuery;
        }
        return url + "?" + buildQuery;
    }


    protected Map<String, Object> handlerRequestParam(Object requestParams) {
        Field[] fields = requestParams.getClass().getDeclaredFields();
        Map<String, Object> paramsMap = new HashMap<>(fields.length);
        for (Field field : fields) {
            field.setAccessible(true);
            Object value;
            try {
                value = field.get(requestParams);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
            String aliasName = getJsonSerializer().getFieldAliasName(field);
            paramsMap.put(aliasName, value);
        }
        return paramsMap;
    }
}
